/*
 *所有关于tb_project_billing类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*tb_project_billingService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using MYData.Core.BaseProvider;
using MYData.Core.Extensions.AutofacManager;
using MYData.Entity.DomainModels;
using System.Linq;
using MYData.Core.Utilities;
using System.Linq.Expressions;
using MYData.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MYData.System.IRepositories;
using System.Threading.Tasks;
using MYData.Core.EFDbContext;
using System;
using System.ComponentModel;
using Mapster;
using System.Collections.Generic;
using MYData.Core.ManageUser;
using MYData.System.IServices;
using Microsoft.Extensions.Hosting;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using System.Diagnostics;
using System.IO;
using System.Threading;
using MYData.Core.DBNpoi;
using Microsoft.AspNetCore.Mvc;
using SixLabors.ImageSharp.Processing.Processors;
using System.Data;
using Microsoft.AspNetCore.Http;
using System.Text.Unicode;
using System.Text;
using NPOI.XWPF.UserModel;
using SqlSugar;
using MYData.Entity.DomainModels.ApiEntity.Dto;

namespace MYData.System.Services
{
    public partial class tb_project_billingService : Itb_project_billingService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly Itb_project_billingRepository _repository;//访问数据库
        private readonly VOLContext _db;
        private static IHostEnvironment _environment;
        private readonly Itb_project_workflowtableRepository _workRepository;
        [ActivatorUtilitiesConstructor]
        public tb_project_billingService(
            Itb_project_billingRepository dbRepository,
            IHttpContextAccessor httpContextAccessor,
            Itb_project_workflowtableRepository workRepository,
            IHostEnvironment iEnvironment,
            VOLContext db
            )
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repository = dbRepository;
            _workRepository = workRepository;
            _environment = iEnvironment;
            _db = db;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }

        /// <summary>
        /// 实例化统一返回值
        /// </summary>
        WebResponseContent webResponse = new WebResponseContent();
        UserInfo userInfo = UserContext.Current.UserInfo;

        #region 入账单列表
        /// <summary>
        /// 获取账单列表
        /// </summary>
        /// <param name="index"当前页数</param>
        /// <param name="size"每页显示数量</param>
        /// <param name="billingUnit"来款单位</param>
        /// <param name="billingTime"账单时间</param>
        public async Task<WebResponseContent> BillingList(string billingUnit = "", string billingTime = "")
        {
            // 从数据库中获取账单列表
            var billinglist = from b in _db.Set<tb_project_billing>().ToList()
                              join y in _db.Set<tb_project_workflowtable>() on b.billingId equals y.projectTableKey
                              where b.isDelete == 0 orderby b.billingTime descending
                              select new
                              {
                                  b.billingId,
                                  b.billingMoney,//账单总金额
                                  b.billingRests,
                                  b.billingTime,
                                  y.auditStatus,
                                  b.createDate,
                                  b.creator,
                                  b.billingUnit,
                                  b.billingBank,
                                  alreadyMoney = SumList(b.billingId),//已分配金额
                                  progress = GetProgress(b.billingId),
                                  operate = GetOperate(b.billingId),
                                  currentOrderId = GetCurrentOrder(b.billingId)
                              };
            // 如果账单单位不为空，则筛选出符合账单单位的账单
            if (!string.IsNullOrEmpty(billingUnit))
            {
                billinglist = billinglist.Where(x => x.billingUnit.Contains(billingUnit));
            }
            //根据入账单时间查询
            if (!string.IsNullOrEmpty(billingTime))
            {
                billinglist = billinglist.Where(x => x.billingTime == DateTime.Parse(billingTime));
            }
            //计算总页数
            //int Count = billinglist.Count();
            // 根据页码和每页大小进行分页
            //billinglist = billinglist.Skip((index - 1) * size).Take(size);
            // 将结果集作为匿名对象返回
            return webResponse.OK("显示成功", billinglist);

        }
        //计算
        private decimal SumList(string billingId)
        {
            //它已经初始化money为0
            decimal alreadyMoney = 0;
            ////查询数据库中isDelete为0且billingId与给定billingId匹配的tb_project_billing_allocation记录
            var billinglist = _db.Set<tb_project_billing_allocation>().Where(x => x.isDelete == 0 && x.billingId == billingId);
            ////然后遍历每条记录
            billinglist.ToList().ForEach(billing =>
            {
                //并将allocationExpenditure的值添加到alreadyMoney中
                alreadyMoney += billing.allocationExpenditure;
            });
            ////回给定billingId的allocationExpenditure值的和。
            return alreadyMoney;
        }

        /// <summary>
        /// 下拨列表的详情/反填
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public WebResponseContent GetDetailBiillingList(string id)
        {
            //var list = _db.Set<tb_project_appendix>().ToList();
            var list = from x in _db.Set<tb_project_billing>().Where(x => x.billingId == id && x.isDelete==0).ToList()
                       //join y in _db.Set<tb_project_billing_allocation>().ToList() on x.billingId equals y.billingId
                       join z in _db.Set<tb_project_appendix>().ToList() on x.billingId equals z.projectID
                       select new
                       {
                           x.billingUnit,
                           x.billingTime,
                           x.billingMoney,
                           z.appendixID,
                           z.appendixUrl,
                           z.appendixName,
                           z.projectID,
                           futureMoney = x.billingMoney - SumList(x.billingId),//未分配金额
                       };
            return webResponse.OK("显示成功", list);
        }

        /// <summary>
        /// 获取流程节点序号
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        /// 2023/4/11 wjq
        private string GetCurrentOrder(string billingId)
        {
            var pro = _db.Set<tb_project_workflowtable>().Where(s => s.projectTableKey == billingId).FirstOrDefault();
            return pro == null ? "0" : pro.currentOrderId;
        }

        /// <summary>
        /// 获取进度
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        /// 2023/4/11 wjq
        private string GetProgress(string billingId)
        {
            //流程表
            var workFlow = _db.Set<Sys_WorkFlow>().Where(s => s.WorkTable == "tb_project_billing").FirstOrDefault();
            //流程项目关系表
            var pro = _db.Set<tb_project_workflowtable>().Where(s => s.projectTableKey == billingId).FirstOrDefault();
            //流程审批节点表
            var step = new Sys_WorkFlowStep();
            if (pro == null)
                return "";
            step = _db.Set<Sys_WorkFlowStep>().Where(s => s.WorkFlow_Id == workFlow.WorkFlow_Id && s.OrderId.ToString() == pro.currentOrderId).FirstOrDefault();
            if (pro.auditStatus == 0)
            {
                return step.StepName;
            }
            if (pro.auditStatus == 1)
            {
                return "审核通过";
            }
            if (pro.auditStatus == 2)
            {
                return "审核未通过";
            }
            return "";
        }


        /// <summary>
        /// 获取操作
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        /// 2023/4/11 wjq
        private string GetOperate(string billingId)
        {
            tb_project_billing billingInfo = _db.Set<tb_project_billing>().Where(s => s.billingId == billingId).FirstOrDefault();
            Sys_WorkFlow workFlow = _db.Set<Sys_WorkFlow>().Where(s => s.WorkTable == "tb_project_billing").FirstOrDefault();
            var pro = _db.Set<tb_project_workflowtable>().Where(s => s.projectTableKey == billingId).FirstOrDefault();
            if (pro == null || pro.auditStatus != 0)
                return "";
            object[] nodes = Newtonsoft.Json.JsonConvert.DeserializeObject<object[]>(workFlow.NodeConfig);
            dto node = Newtonsoft.Json.JsonConvert.DeserializeObject<dto>(nodes[Convert.ToInt32(pro.currentOrderId) - 1].ToString());
            var step = new Sys_WorkFlowStep();

            step = _db.Set<Sys_WorkFlowStep>().Where(s => s.WorkFlow_Id == workFlow.WorkFlow_Id && s.OrderId.ToString() == pro.currentOrderId).FirstOrDefault();
            //负责人返回操作
            if (pro.currentOrderId == "2" && billingInfo.creator == userInfo.UserName)
            {
                return step.StepName;
            }
            //根据角色操作
            if (userInfo.Role_Id.ToString() == node.roleId)
            {
                return step.StepName;
            }
            //根据指定用户操作
            if (userInfo.User_Id.ToString() == node.userId)
            {
                return step.StepName;
            }
            //根据部门操作
            if (userInfo.DeptId.ToString() == node.deptId)
            {
                return step.StepName;
            }
            return "";
        }
        #endregion

        #region 入账单添加
        /// <summary>
        /// 入账单添加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public WebResponseContent BiillingAdd(tb_project_billing_appendixDto input)
        {
            //开始事务
            _db.Database.BeginTransaction();
            try
            {
                //定义一个雪花id
                string billingId = new Snowflake.Core.IdWorker(1, 1).NextId().ToString();
                //将Dto转换为实体
                var billingInfo = input.Adapt<tb_project_billing>();
                billingInfo.billingId = billingId;
                var appendixInfo = input.file.Adapt<List<tb_project_appendix>>();
                //流程关系表添加
                tb_project_workflowtable workflowtable = new tb_project_workflowtable();
                //查询流程表中是否有这个表
                var workFlow = _db.Set<Sys_WorkFlow>().Where(x => x.WorkTable == "tb_project_billing").FirstOrDefault();
                workflowtable.workFlowId = workFlow.WorkFlow_Id;
                workflowtable.workName = workFlow.WorkName;
                workflowtable.projectTableKey = billingId;
                workflowtable.projectTable = workFlow.WorkTable;
                workflowtable.workTableName = workFlow.WorkTableName;
                workflowtable.currentOrderId = "1";//审批节点
                workflowtable.auditStatus = 0;//0默认为审核中
                workflowtable.createDate = DateTime.Now;
                workflowtable.creator = userInfo.UserName;
                foreach (var item in appendixInfo)
                {
                    item.projectID = billingInfo.billingId;
                }

                //添加获取到的信息
                _db.Set<tb_project_billing>().Add(billingInfo);
                //流程关系表添加
                _workRepository.Add(workflowtable, false);
                if (_db.SaveChanges() < 1)
                {
                    //回滚
                    _db.Database.RollbackTransaction();
                    return webResponse.OK("入账单添加失败!");
                }
                _db.Set<tb_project_appendix>().AddRange(appendixInfo);
                if (_db.SaveChanges() < 1)
                {
                    //回滚
                    _db.Database.RollbackTransaction();
                    return webResponse.OK("附件添加失败!");
                }
                //提交事务
                _db.Database.CommitTransaction();
                return webResponse.OK("添加成功", true);
            }
            catch (Exception)
            {
                //回滚
                _db.Database.RollbackTransaction();
                return webResponse.OK("添加失败!");
            }

        }
        #endregion

        #region 导出Excel
        /// <summary>
        /// Excel数据导出
        /// </summary>
        /// <returns></returns>
        public WebResponseContent ExcelDataExport()
        {
            var excelFilePath = "";
            var time = "";
            //Excel导出名称
            string excelName = "入账单";
            try
            {
                //实例化一个计时器
                Stopwatch stopWatch = new Stopwatch();
                //开始计时
                stopWatch.Start();
                //首先创建Excel文件对象
                var workbook = new HSSFWorkbook();
                //创建工作表，也就是Excel中的sheet，给工作表赋一个名称(Excel底部名称)
                var sheet = workbook.CreateSheet("入账单");
                //TODO:是否开始Excel导出后公式仍然有效（非必须）
                sheet.ForceFormulaRecalculation = true;

                #region table 表格内容设置

                #region 标题样式

                //设置顶部大标题样式
                var cellStyleFont = NpoiHelper._.CreateStyle(workbook, HorizontalAlignment.Center, VerticalAlignment.Center, 20, true, 700, "楷体", true, false, false, true, FillPattern.SolidForeground, HSSFColor.Coral.Index, HSSFColor.White.Index,
                    FontUnderlineType.None, FontSuperScript.None, false);

                //第一行表单
                var row = NpoiHelper._.CreateRow(sheet, 0, 28);
                //根据行数进行创建单元格
                var cell = row.CreateCell(0);
                //合并单元格 例： 第1行到第2行 第3列到第4列围成的矩形区域

                //TODO:关于Excel行列单元格合并问题
                /**
                  第一个参数：从第几行开始合并
                  第二个参数：到第几行结束合并
                  第三个参数：从第几列开始合并
                  第四个参数：到第几列结束合并
                **/
                //第一行合并6个单元格
                CellRangeAddress region = new CellRangeAddress(0, 0, 0, 6);
                //向工作表添加合并的区域
                sheet.AddMergedRegion(region);
                //合并单元格后，只需对第一个位置赋值即可（TODO:顶部标题）
                cell.SetCellValue("入账单");
                //标题样式
                cell.CellStyle = cellStyleFont;
                //二级标题列样式设置
                var headTopStyle = NpoiHelper._.CreateStyle(workbook, HorizontalAlignment.Center, VerticalAlignment.Center, 13, true, 700, "楷体", true, false, false, true, FillPattern.SolidForeground, HSSFColor.Grey25Percent.Index, HSSFColor.Black.Index,
                FontUnderlineType.None, FontSuperScript.None, false);
                //表头名称
                var headerName = new[] { "账单编号", "来款单位", "到账金额（元）", "财务到账时间", "银行卡号", "摘要", "其他" };
                //创建第二行
                row = NpoiHelper._.CreateRow(sheet, 1, 24);
                //根据表头名称个数来创建单元格
                for (var i = 0; i < headerName.Length; i++)
                {
                    cell = NpoiHelper._.CreateCells(row, headTopStyle, i, headerName[i]);
                    //设置单元格宽度
                    if (headerName[i] == "摘要" || headerName[i] == "其他")
                    {
                        sheet.SetColumnWidth(i, 10000);
                    }
                    else

                    {
                        sheet.SetColumnWidth(i, 5000);
                    }

                }
                #endregion


                #region 单元格内容信息

                //单元格边框样式
                var cellStyle = NpoiHelper._.CreateStyle(workbook, HorizontalAlignment.Center, VerticalAlignment.Center, 8, true, 400);
                //获取list数据源
                var billinglist = _db.Set<tb_project_billing>().Where(x => x.isDelete == 0).ToList();
                //获取总条数
                int count = billinglist.Count();
                int number = 1;
                //根据条数创建单元格
                for (int i = 0; i < count; i++)
                {
                    //sheet.CreateRow(i+2);//在上面表头的基础上创建行
                    row = NpoiHelper._.CreateRow(sheet, i + 2, 20);
                    //创建单元格列
                    cell = NpoiHelper._.CreateCells(row, cellStyle, 0, billinglist[i].billingId);
                    cell = NpoiHelper._.CreateCells(row, cellStyle, 1, billinglist[i].billingUnit);
                    cell = NpoiHelper._.CreateCells(row, cellStyle, 2, billinglist[i].billingMoney.ToString());
                    cell = NpoiHelper._.CreateCells(row, cellStyle, 3, billinglist[i].billingTime.ToString("yyyy-MM-dd"));
                    cell = NpoiHelper._.CreateCells(row, cellStyle, 4, billinglist[i].billingBank);
                    cell = NpoiHelper._.CreateCells(row, cellStyle, 5, billinglist[i].billingAbstract);
                    cell = NpoiHelper._.CreateCells(row, cellStyle, 6, billinglist[i].billingRests);

                    number++;
                }
                #endregion

                #endregion

                string folder = DateTime.Now.ToString("yyyyMMdd");
                //保存文件到静态资源文件夹中（wwwroot）,使用绝对路径
                var uploadPath = _environment.ContentRootPath + "/wwwroot/ExcelFile/" + folder + "/";

                //excel保存文件名
                string excelFileName = excelName + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";

                //创建目录文件夹
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }

                //Excel的路径及名称
                string excelPath = uploadPath + excelFileName;

                //使用FileStream文件流来写入数据（传入参数为：文件所在路径，对文件的操作方式，对文件内数据的操作）
                var fileStream = new FileStream(excelPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                //向Excel文件对象写入文件流，生成Excel文件
                workbook.Write(fileStream);

                //关闭文件流
                fileStream.Close();

                //释放流所占用的资源
                fileStream.Dispose();

                //excel文件保存的相对路径，提供前端下载
                var relativePositioning = "/ExcelFile/" + folder + "/" + excelFileName;

                excelFilePath = relativePositioning;
                Thread.Sleep(1000);
                stopWatch.Stop();
                time = stopWatch.ElapsedMilliseconds.ToString();
            }
            catch (Exception e)
            {
                return webResponse.Error(e.Message);
            }
            return webResponse.OK($"导出成功，用时{time}毫秒", excelFilePath);
        }
        #endregion

        #region 批量导入
        public WebResponseContent ExcelDataImport(IFormFile file)
        {
            //实例化计时器
            var stopWatch = new Stopwatch();
            //实例DataTable数据源
            var getDataTable = new DataTable();
            try
            {
                //判断是否接收到文件
                if (file.Length > 0)
                {
                    //开始计时
                    stopWatch.Start();
                    //将Excel表格的数据转换为DataTable数据
                    getDataTable = NpoiExcelImportHelper._.ExcelToDataTable(file.OpenReadStream(), Path.GetExtension(file.FileName));
                    //判断数据总行数
                    if (getDataTable.Rows.Count <= 0)
                    {
                        return webResponse.Error("Excel表格中没有数据");
                    }
                    //实例化List数据源
                    var billingList = new List<tb_project_billing>();
                    //根据总行数循环，为每一个字段赋值
                    for (int i = 0; i < getDataTable.Rows.Count; i++)
                    {
                        var billing = new tb_project_billing
                        {
                            billingUnit = getDataTable.Rows[i][0].ToString(),
                            billingMoney = getDataTable.Rows[i][1].ToDecimal(),
                            billingTime = getDataTable.Rows[i][2].ToDateTime(),
                            billingBank = getDataTable.Rows[i][3].ToString(),
                            billingAbstract = getDataTable.Rows[i][4].ToString(),
                            billingRests = getDataTable.Rows[i][5].ToString()
                        };
                        billingList.Add(billing);
                    }
                    //批量添加数据
                    _db.tb_Project_Billings.AddRange(billingList);
                    //修改同步到数据库
                    _db.SaveChanges();
                    //停止计时
                    stopWatch.Stop();
                }
            }
            catch (Exception ex)
            {
                return webResponse.Error(ex.Message);
            }
            return webResponse.OK($"导入成功，用时{stopWatch.Elapsed.TotalSeconds}秒，共导入{getDataTable.Rows.Count}条数据");
        }
        #endregion

        #region 导出Word
        public WebResponseContent SaveWordFile()
        {
            string savePath = "";
            var time = "";
            try
            {
                var stopWatch = new Stopwatch();
                stopWatch.Start();
                //获取当前日期
                string currentDate = DateTime.Now.ToString("yyyyMMddHHmmss");
                //入账单导出日期
                string checkTime = DateTime.Now.ToString("yyyy年MM月dd日");
                //根据创建日期保存文件到静态资源文件夹下
                var uploadPath = _environment.ContentRootPath + "/wwwroot/SaveWordFile/" + checkTime + "/";
                //Word文档标题
                string workFileName = "入账单" + currentDate;
                string fileName = string.Format("{0}.docx", workFileName, Encoding.UTF8);
                //判断文件夹是否存在
                if (!Directory.Exists(uploadPath))
                {
                    //不存在就会创建文件夹
                    Directory.CreateDirectory(uploadPath);
                }

                //使用FileStream文件流来写入数据（传入参数为：文件所在路径，对文件的操作方式，对文件内数据的操作）
                //通过使用文件流，创建文件流对象，向文件流中写入内容，并保存为Word文档格式
                using (var stream = new FileStream(Path.Combine(uploadPath, fileName), FileMode.Create, FileAccess.Write))
                {
                    //创建word文档
                    XWPFDocument document = new XWPFDocument();
                    //文本标题
                    document.SetParagraph(NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, checkTime + "入账单", true, 19, "宋体", ParagraphAlignment.CENTER), 0);
                    //将list数据源转换为DataTable数据源
                    string jsonlist = Newtonsoft.Json.JsonConvert.SerializeObject(_db.Set<tb_project_billing>().Where(x => x.isDelete == 0).Select(x => new { x.billingId, x.billingUnit, x.billingTime, x.billingMoney, x.billingBank, x.billingAbstract, x.billingRests }).ToList());
                    DataTable dt = Newtonsoft.Json.JsonConvert.DeserializeObject<DataTable>(jsonlist);
                    //列数由自己定义
                    int cols = dt.Columns.Count;
                    //获取总行数
                    int count = dt.Rows.Count;
                    //创建表格对象实例（count+1）是由于第一行被设置为标题，所以需要加一行
                    XWPFTable xwpfTable = document.CreateTable(count + 1, cols);
                    //总宽度
                    xwpfTable.Width = 4900;
                    //给每一列单元格设置列宽
                    xwpfTable.SetColumnWidth(0, 700);
                    xwpfTable.SetColumnWidth(1, 700);
                    xwpfTable.SetColumnWidth(2, 700);
                    xwpfTable.SetColumnWidth(3, 700);
                    xwpfTable.SetColumnWidth(4, 700);
                    xwpfTable.SetColumnWidth(5, 700);
                    xwpfTable.SetColumnWidth(6, 700);
                    //给第一行设置为标题
                    xwpfTable.GetRow(0).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, xwpfTable, "账单编号", ParagraphAlignment.CENTER, 25, true));
                    xwpfTable.GetRow(0).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, xwpfTable, "来款单位", ParagraphAlignment.CENTER, 25, true));
                    xwpfTable.GetRow(0).GetCell(2).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, xwpfTable, "财务到账时间", ParagraphAlignment.CENTER, 25, true));
                    xwpfTable.GetRow(0).GetCell(3).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, xwpfTable, "到账金额（元）", ParagraphAlignment.CENTER, 25, true));
                    xwpfTable.GetRow(0).GetCell(4).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, xwpfTable, "银行卡号", ParagraphAlignment.CENTER, 25, true));
                    xwpfTable.GetRow(0).GetCell(5).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, xwpfTable, "摘要", ParagraphAlignment.CENTER, 25, true));
                    xwpfTable.GetRow(0).GetCell(6).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, xwpfTable, "其他", ParagraphAlignment.CENTER, 25, true));
                    //从表格第二行开始给数据赋值（排除第一行标题）
                    for (int j = 1; j < count + 1; j++)
                    {
                        //根据列数循环
                        for (int i = 0; i < cols; i++)
                        {
                            //根据行数循环
                            for (int z = 0; z < count; z++)
                            {
                                xwpfTable.GetRow(j).GetCell(i).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, xwpfTable, dt.Rows[z][i].ToString(), ParagraphAlignment.CENTER, 22, true));
                            }
                        }
                    }

                    //向文档流中写入内容，生成word
                    document.Write(stream);
                    //文件保存的相对路径（可以让前端进行下载）
                    savePath = "/SaveWordFile/" + currentDate + "/" + fileName;
                    //停止计时
                    stopWatch.Stop();
                    //获取执行时间（秒）
                    time = stopWatch.Elapsed.TotalSeconds.ToString();
                }
            }
            catch (Exception ex)
            {
                return webResponse.Error(ex.Message);
            }
            return webResponse.OK($"导出成功，用时{time}秒", savePath);
        }
        #endregion

        #region 详情/反填
        /// <summary>
        /// 入账单列表的详情/回显
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// WJQ 2023/4/14
        public async Task<WebResponseContent> GetDetailBiilling(string id)
        {
            var list = from y in _db.Set<tb_project_billing>().Where(x => x.billingId == id)
                       join z in _db.Set<tb_project_appendix>() on y.billingId equals z.projectID
                       select new
                       {
                           y.billingUnit,
                           y.billingTime,
                           y.billingMoney,
                           z.appendixID,
                           z.appendixUrl,
                           z.appendixName,
                           z.projectID,
                           y.billingRests,
                           y.billingBank,
                           y.billingAbstract,
                           y.billingId,
                       };
            return webResponse.OK("显示成功", list);
        }
        #endregion

        private class dto
        {

            public string? id { get; set; }
            public string? name { get; set; }
            public string? type { get; set; }
            public string? left { get; set; }
            public string? top { get; set; }
            public string? ico { get; set; }
            public string? state { get; set; }
            public string? stepValue { get; set; }
            public string? nodeType { get; set; }
            public string? userId { get; set; }
            public string? roleId { get; set; }
            public string? deptId { get; set; }

        }
    }

}
